package eu.urbain.gdocslauncher;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.util.Arrays;

import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;

public class DriveCommandLine {

	private static String CLIENT_ID = "836326172472-ios9hckkail92gp8ugcat2rp6e17rvso.apps.googleusercontent.com";
	private static String CLIENT_SECRET = "fYd3zWj6t3dPvG-t3eXLvXPE";

	// private static String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
	private static String REDIRECT_URI = "http://localhost:8080";

	public static void main(String[] args) throws IOException {

		GDocsLauncherConfig gDocsLauncherConfig;

		GoogleCredential credential;

		HttpTransport httpTransport = new NetHttpTransport();

		JsonFactory jsonFactory = new JacksonFactory();

		gDocsLauncherConfig = loadConfig();

		if (gDocsLauncherConfig == null) {

			GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET,
					Arrays.asList(DriveScopes.DRIVE)).setAccessType("offline").setApprovalPrompt("force").build();

			String url = flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI).build();
			System.out.println("Please open the following URL in your browser then type the authorization code:");
			System.out.println("  " + url);

			URL url2 = new URL(url);
			Common.openWebpage(url2);

			/*
			 * https://accounts.google.com/o/oauth2/auth? access_type=online&
			 * approval_prompt=auto&
			 * client_id=836326172472-ios9hckkail92gp8ugcat2rp6e17rvso
			 * .apps.googleusercontent.com&
			 * redirect_uri=urn:ietf:wg:oauth:2.0:oob& response_type=code&
			 * scope=https://www.googleapis.com/auth/drive
			 */

			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			String code = br.readLine();

			GoogleTokenResponse response = flow.newTokenRequest(code).setRedirectUri(REDIRECT_URI).execute();

			gDocsLauncherConfig = new GDocsLauncherConfig();
			gDocsLauncherConfig.setRefreshToken(response.getRefreshToken());
			gDocsLauncherConfig.setAccessToken(response.getAccessToken());

			System.out.println("refresh token : " + gDocsLauncherConfig.getRefreshToken());
			System.out.println("access token : " + gDocsLauncherConfig.getAccessToken());

			// credential = new
			// GoogleCredential().setFromTokenResponse(response);

			saveConfig(gDocsLauncherConfig);

		}

		credential = new GoogleCredential.Builder().setClientSecrets(CLIENT_ID, CLIENT_SECRET).setJsonFactory(jsonFactory).setTransport(httpTransport).build()
				.setRefreshToken(gDocsLauncherConfig.getRefreshToken()).setAccessToken(gDocsLauncherConfig.getAccessToken());

		// Create a new authorized API client
		Drive service = new Drive.Builder(httpTransport, jsonFactory, credential).setApplicationName("gDocsLauncher").build();

		// Insert a file
		File body = new File();
		body.setTitle("document.txt");
		body.setDescription("A test document");
		body.setMimeType("text/plain");

		java.io.File currentDir = new java.io.File(".");
		String basePath = currentDir.getCanonicalPath();

		System.out.println(basePath);
		String documentTxtPath = basePath + "\\src\\resources\\document.txt";
		System.out.println(documentTxtPath);

		java.io.File fileContent = new java.io.File(documentTxtPath);
		FileContent mediaContent = new FileContent("text/plain", fileContent);

		File file = service.files().insert(body, mediaContent).execute();
		System.out.println("File ID: " + file.getId());
	}

	public static boolean saveConfig(GDocsLauncherConfig gDocsLauncherConfig) {

		try {
			// Catch errors in I/O if necessary.
			// Open a file to write to, named SavedObj.sav.
			FileOutputStream saveFile = new FileOutputStream("gDocsLauncher.conf");

			// Create an ObjectOutputStream to put objects into save file.
			ObjectOutputStream save = new ObjectOutputStream(saveFile);

			// Now we do the save.
			save.writeObject(gDocsLauncherConfig);

			// Close the file.
			save.close(); // This also closes saveFile.
			System.out.println("Config save successfully");
		} catch (Exception exc) {
			System.out.println("Config save failed");
			exc.printStackTrace();
			return false;
		}

		return true;

	}

	public static GDocsLauncherConfig loadConfig() {

		try {
			// Open file to read from, named SavedObj.sav.
			FileInputStream saveFile = new FileInputStream("gDocsLauncher.conf");

			// Create an ObjectInputStream to get objects from save file.
			ObjectInputStream save = new ObjectInputStream(saveFile);

			// Now we do the restore.
			// readObject() returns a generic Object, we cast those back
			// into their original class type.
			// For primitive types, use the corresponding reference class.
			GDocsLauncherConfig gDocsLauncherConfig = (GDocsLauncherConfig) save.readObject();

			// Close the file.
			save.close();
			// This also closes saveFile.

			System.out.println("Config load successfully");

			return gDocsLauncherConfig;

		} catch (Exception exc) {

			System.out.println("Config load failed");
			exc.printStackTrace();
			return null;
		}

	}

}